Skip to content

feat(image-editor): Lasso + PolyLasso + Magic Wand selection family + Fullscreen UX#44

Merged
lyfuci merged 1 commit intomainfrom
feat/image-editor-lasso-wand
Apr 25, 2026
Merged

feat(image-editor): Lasso + PolyLasso + Magic Wand selection family + Fullscreen UX#44
lyfuci merged 1 commit intomainfrom
feat/image-editor-lasso-wand

Conversation

@lyfuci
Copy link
Copy Markdown
Owner

@lyfuci lyfuci commented Apr 25, 2026

Summary

Three new selection tools + two PS-alignment UX fixes.

Selection tools (Lasso, Polygonal Lasso, Magic Wand)

  • Lasso (L) — drag to trace a freeform region; release to close. Path subsamples to ≥2 px between points so memory stays bounded on slow drags.
  • Polygonal Lasso — click-by-click vertex chain with a rubber-band preview from the last vertex to the cursor. Click within 8 px of the first vertex (or hit Esc) to close. Vertex dots are orange (first) and white (rest) so it's obvious where you've clicked.
  • Magic Wand (W) — reuses the Paint Bucket's scanline flood fill; stores the bbox of the matched region as a rectangular selection. Tolerance is exposed in the options bar (0–128, slider + number).

State changes

  • New optional EditorState.selectionPath?: Point[] — when present, refines the selection outline from the bbox rect to a closed polygon. Rendered via a new drawSelectionPathChrome helper (black halo + white marching-ants dashes, identical look to the marquee but along an arbitrary path).
  • serializeProject round-trips selectionPath so polygon selections survive .json save / reload.
  • Cmd/Ctrl+D and the "Deselect" button now clear both selection and selectionPath (formerly only the rect). Marquee commit explicitly clears selectionPath so a stale polygon doesn't outline a fresh rectangular selection.

Canvas additions

  • New interaction kinds: lasso-drawing, polylasso-drawing.
  • CanvasHandle gains hasPendingPolyLasso and cancelPendingPolyLasso, mirroring the existing crop pair so Esc in the parent's keyboard handler cancels the pending vertex chain cleanly.

OptionsBar

  • Marquee / Lasso / PolyLasso share one variant (hint + "Deselect" button when active).
  • Wand gets its own variant: tolerance number + range slider, hint, "Deselect".
  • Hand gets a hint variant.

UX fixes (bundled)

  • F shortcut unbound — Photoshop's F cycles screen modes, not "toggle fullscreen UI"; freeing the key avoids the muscle-memory clash.
  • Green Fullscreen button in the tab strip's right corner (turns red when active, indicating "click to exit"). Replaces the muted "⛶ F" tab.
  • Hand tool (H) is no longer a stub — selecting it puts the editor into pan mode (same as holding Space). New effectivePanMode = panMode || tool === 'hand' is wired into both Workspace and Canvas.

i18n

New keys (en + zh-CN): lassoHint, polyLassoHint, wandHint, wandTolerance, wandEmpty, handHint. Updated focusEnterHint / focusExitHint to drop the F reference.

Test plan

  • L: drag a freeform path, release — selection appears with marching-ants polygon outline. Survives undo/redo.
  • PolyLasso: click vertices, click near the first vertex (or Esc) — polygon closes / cancels.
  • W: click on a uniform region — bbox of matching pixels becomes the selection. Adjust tolerance, click again — bbox grows/shrinks.
  • Marquee → Lasso → Marquee: switching tools doesn't leak a stale polygon outline.
  • Save .json → reload — both rect and polygon selections round-trip.
  • Cmd/Ctrl+D + Deselect button clear the selection regardless of source tool.
  • Crop applied → selection with each new tool — coords align to the cropped image.
  • H: cursor becomes grab; drag pans the canvas. Press F: nothing happens (unbound). Click green "⛶ Fullscreen" — UI hides; button turns red "⛶ Exit fullscreen". Click again or hit Esc to exit.

🤖 Generated with Claude Code

…on family

Three more PS-aligned selection tools join Marquee end-to-end:

- **Lasso (L)**: drag to trace a freeform region; release to close. Path
  subsamples to ≥2 px between points to keep memory bounded.
- **Polygonal Lasso**: click-by-click vertex chain with a rubber-band
  preview from the last vertex to the cursor. Click within 8 px of the
  first vertex (or hit Esc) to close. Vertex dots — orange first, white
  rest — make it obvious where you've clicked.
- **Magic Wand (W)**: reuses the Paint Bucket's scanline flood fill;
  stores the bbox of the matched region as a rect selection. Tolerance
  is exposed in the options bar (0–128, slider + number).

State changes:

- `EditorState.selectionPath?: Point[]` — when present, refines the
  selection outline from the bbox rect to a closed polygon. Render adds
  a `drawSelectionPathChrome` helper (same black-halo + white-dashes
  marching-ants look as the marquee, but along an arbitrary path).
- `serializeProject` round-trips `selectionPath` so polygon selections
  survive .json save / reload.
- Cmd/Ctrl+D and the "Deselect" button now clear both `selection` and
  `selectionPath` (formerly only the rect).
- Marquee commit explicitly clears `selectionPath` so a stale polygon
  doesn't outline a fresh rectangular selection.

Canvas additions:

- New interaction kinds: `lasso-drawing`, `polylasso-drawing`.
- New imperative methods on `CanvasHandle`: `hasPendingPolyLasso` and
  `cancelPendingPolyLasso`, mirroring the existing crop pair so Esc in
  the parent's keyboard handler cancels the pending vertex chain
  cleanly.

OptionsBar:

- Marquee/Lasso/PolyLasso share one variant (hint + Deselect button)
  switched by `hintKey`.
- Wand gets its own variant: tolerance number + range, hint, Deselect.

i18n: new keys `lassoHint`, `polyLassoHint`, `wandHint`,
`wandTolerance`, `wandEmpty` in both en and zh-CN.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lyfuci lyfuci merged commit 17f40b0 into main Apr 25, 2026
2 checks passed
@lyfuci lyfuci changed the title feat(image-editor): wire Lasso + Polygonal Lasso + Magic Wand selection family feat(image-editor): Lasso + PolyLasso + Magic Wand selection family + Fullscreen UX Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant